#ifndef BOITE_H
#define BOITE_H

#include <vector>

#include "Observateur.h"
#include "Couleur.h"
#include "Image.h"
#include "Objet.h"
#include "Vecteur.h"
#include "Source.h"

struct BoiteEnglobante
  {
    /// coin droit
    Point corner1;
    /// coin gauche
    Point corner2;

	BoiteEnglobante& operator=(BoiteEnglobante const& be)
	{
		corner1 = be.corner1;
		corner2 = be.corner2;

		return *this;
	}

	bool getEntryExitDistances(Rayon ray, float tnear, float tfar)
    {
	  float tfarX, tfarY, tfarZ, tnearX, tnearY, tnearZ;
      tfar = std::numeric_limits<float>::max();
      tnear = std::numeric_limits<float>::epsilon();
      for(int i = 0; i < 3; ++i)
      {
		    float posX = ray.getOrigine().getX() + tfar * ray.getDirection().getX();
		    float posY = ray.getOrigine().getY() + tfar * ray.getDirection().getY();
		    float posZ = ray.getOrigine().getZ() + tfar * ray.getDirection().getZ();

			float pos_nearX = ray.getOrigine().getX() + tnear * ray.getDirection().getX();
		    float pos_nearY = ray.getOrigine().getY() + tnear * ray.getDirection().getY();
		    float pos_nearZ = ray.getOrigine().getZ() + tnear * ray.getDirection().getZ();
			

			if(ray.getDirection().getX() < 0 || ray.getDirection().getY() <0 || ray.getDirection().getZ()<0)
			{
				if(posX < corner1.getX())
				  {
					tfarX = (corner1.getX() - ray.getOrigine().getX()) / ray.getDirection().getX();
				  }
				else if(posX > corner2.getX())
				  {
					tfarX = std::numeric_limits<float>::epsilon();
				  }
				if(posY < corner1.getY())
				  {
					tfarY = (corner1.getY() - ray.getOrigine().getY()) / ray.getDirection().getY();
				  }
				else if(posY > corner2.getY())
				  {
					tfarY = std::numeric_limits<float>::epsilon();
				  }
				if(posZ < corner1.getZ())
				  {
					tfarZ = (corner1.getZ() - ray.getOrigine().getZ()) / ray.getDirection().getZ();
				  }
				else if(posZ > corner2.getZ())
				  {
					tfarZ = std::numeric_limits<float>::epsilon();
				  }
				if(pos_nearX > corner2.getX())
				  {
					tnearX = (corner2.getX() - ray.getOrigine().getX()) / ray.getDirection().getX();
				  }
				  else if(pos_nearX < corner2.getX())
				  {
					tnearX = std::numeric_limits<float>::max();
				  }
				if(pos_nearY > corner2.getY())
				  {
					tnearY = (corner2.getY() - ray.getOrigine().getY()) / ray.getDirection().getY();
				  }
				  else if(pos_nearY < corner2.getY())
				  {
					tnearY = std::numeric_limits<float>::max();
				  }
				if(pos_nearZ > corner2.getZ())
				  {
					tnearZ = (corner2.getZ() - ray.getOrigine().getZ()) / ray.getDirection().getZ();
				  }
				  else if(pos_nearZ < corner2.getZ())
				  {
					tnearZ = std::numeric_limits<float>::max();
				  }
			}
			else if (ray.getDirection().getX() > 0 || ray.getDirection().getY() >0 || ray.getDirection().getZ()>0)
			{
				if(posX > corner2.getX())
				  {
					  tfarX = (corner2.getX() - ray.getOrigine().getX()) / ray.getDirection().getX();
				  }
				  else if(posX < corner1.getX())
				  {
					tfarX = std::numeric_limits<float>::epsilon();
				  }

				  if(posY > corner2.getY())
				  {
					  tfarY = (corner2.getY() - ray.getOrigine().getY()) / ray.getDirection().getY();
				  }
				  else if(posY < corner1.getY())
				  {
					tfarY = std::numeric_limits<float>::epsilon();
				  }

				  if(posZ > corner2.getZ())
				  {
					  tfarZ = (corner2.getZ() - ray.getOrigine().getZ()) / ray.getDirection().getZ();
				  }
				  else if(posZ < corner1.getZ())
				  {
					tfarZ = std::numeric_limits<float>::epsilon();
				  }

				  if(pos_nearX <  corner1.getX())
				  {
					  tnearX = ( corner1.getX() - ray.getOrigine().getX()) / ray.getDirection().getX();
				  }
				  else if(pos_nearX > corner2.getX())
				  {
					tnearX = std::numeric_limits<float>::max();
				  }

				   if(pos_nearY <  corner1.getY())
				  {
					  tnearY = ( corner1.getY() - ray.getOrigine().getY()) / ray.getDirection().getY();
				  }
				  else if(pos_nearY > corner2.getY())
				  {
					tnearY = std::numeric_limits<float>::max();
				  }

				  if(pos_nearZ <  corner1.getZ())
				  {
					  tnearZ = ( corner1.getZ() - ray.getOrigine().getZ()) / ray.getDirection().getZ();
				  }
				  else if(pos_nearZ > corner2.getZ())
				  {
					tnearZ = std::numeric_limits<float>::max();
				  }
			}
        
			if (tnearX > tfarX || tnearY > tfarY || tnearZ > tfarZ)
			{
			  return false;
			}
		  }

		  return true;
		}

  };



#endif